package com.newsvoice.activity;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.google.gson.Gson;

public class WebService extends AsyncTask<Void, Void, String> {
	private ProgressDialog dialog;

	public static final String POST_METHOD = "POST";
	public static final String GET_METHOD = "GET";

	static final String WSC_TAG = "RESTWebService";

	private DefaultHttpClient httpClient;
	private HttpContext localContext;
	private String ret;

	HttpResponse response = null;
	HttpPost httpPost = null;
	HttpGet httpGet = null;
	String webServiceUrl;
	private String methodName;
	private String method = GET_METHOD;
	private Map<String, String> params;
	private ICallbackHandler callback;
	private Context context;

	public WebService(String serviceName, String mName,
			Map<String, String> params, ICallbackHandler hndl, String method,
			Context context) {
		HttpParams myParams = new BasicHttpParams();
		this.context = context;
		HttpConnectionParams.setConnectionTimeout(myParams, 100000);
		HttpConnectionParams.setSoTimeout(myParams, 100000);
		httpClient = new DefaultHttpClient(myParams);
		localContext = new BasicHttpContext();
		webServiceUrl = serviceName;
		methodName = mName;
		this.params = params;
		callback = hndl;

		this.method = method;
	}

	// Use this method to do a HttpPost\WebInvoke on a Web Service
	public String webInvoke(String methodName, Map<String, String> params) {

		JSONObject jsonObject = new JSONObject();

		for (Map.Entry<String, String> param : params.entrySet()) {
			try {
				jsonObject.put(param.getKey(), param.getValue());
			} catch (JSONException e) {
				Log.e(WSC_TAG, "JSONException : " + e);
			}
		}
		return webInvoke(methodName, jsonObject.toString(), "application/json");
	}

	private String webInvoke(String methodName, String data, String contentType) {
		ret = null;

		httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY,
				CookiePolicy.RFC_2109);

		httpPost = new HttpPost(webServiceUrl + methodName);
		response = null;

		StringEntity tmp = null;

		// httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE");
		httpPost.setHeader(
				"Accept",
				"text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");

		if (contentType != null) {
			httpPost.setHeader("Content-Type", contentType);
		} else {
			httpPost.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
		}

		try {
			tmp = new StringEntity(data, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			Log.e(WSC_TAG, "HttpUtils : UnsupportedEncodingException : " + e);
		}

		httpPost.setEntity(tmp);

		Log.d(WSC_TAG, webServiceUrl + "?" + data);

		try {
			response = httpClient.execute(httpPost, localContext);

			if (response != null) {
				ret = EntityUtils.toString(response.getEntity());
			} else {
				Log.e(WSC_TAG, "Empty response");

			}
		} catch (Exception e) {
			Log.e(WSC_TAG, "HttpUtils: " + e);
		}

		return ret;
	}

	// Use this method to do a HttpGet/WebGet on the web service
	public String webGet(String methodName, Map<String, String> params) {
		String getUrl = webServiceUrl + methodName;

		int i = 0;
		for (Map.Entry<String, String> param : params.entrySet()) {
			if (i == 0) {
				getUrl += "?";
			} else {
				getUrl += "&";
			}

			try {
				getUrl += param.getKey() + "="
						+ URLEncoder.encode(param.getValue(), "UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			i++;
		}

		httpGet = new HttpGet(getUrl);
		Log.d(WSC_TAG, getUrl);

		try {
			response = httpClient.execute(httpGet);

		} catch (Exception e) {
			if (e != null && e.getMessage() != null)
				Log.e(WSC_TAG, e.getMessage());
			else if (e != null)
				Log.e(WSC_TAG, e.toString());
			else
				Log.e(WSC_TAG, "NULL Exception");
		}

		// we assume that the response body contains the error message
		try {

			ret = EntityUtils.toString(response.getEntity());
		} catch (IOException e) {
			Log.e(WSC_TAG, e.getMessage());
		}

		return ret;
	}

	public static JSONObject Object(Object o) {
		try {
			return new JSONObject(new Gson().toJson(o));
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return null;
	}

	public InputStream getHttpStream(String urlString) throws IOException {
		InputStream in = null;
		int response = -1;

		URL url = new URL(urlString);
		URLConnection conn = url.openConnection();

		if (!(conn instanceof HttpURLConnection))
			throw new IOException("Not an HTTP connection");

		try {
			HttpURLConnection httpConn = (HttpURLConnection) conn;
			httpConn.setAllowUserInteraction(false);
			httpConn.setInstanceFollowRedirects(true);
			httpConn.setRequestMethod("GET");
			httpConn.connect();

			response = httpConn.getResponseCode();

			if (response == HttpURLConnection.HTTP_OK) {
				in = httpConn.getInputStream();
			}
		} catch (Exception e) {
			throw new IOException("Error connecting");
		} // end try-catch

		return in;
	}

	public void clearCookies() {
		httpClient.getCookieStore().clear();
	}

	public void abort() {
		try {
			if (httpClient != null) {
				httpPost.abort();
			}
		} catch (Exception e) {

		}
	}

	@Override
	protected void onPreExecute() {
		if (context != null) {
			ShowNewsActivity.dialog = new ProgressDialog(context);
			ShowNewsActivity.dialog.setMessage("Please wait...");
			ShowNewsActivity.dialog.show();
		}
	}

	@Override
	protected String doInBackground(Void... prs) {
		if (method.equals(GET_METHOD)) {
			String response = null;
			
			try {
				response = webGet(methodName, params);
			} catch (Exception e) {
				response = "error";
			}
			
			return response;
		}
		else if (method.equals(POST_METHOD)) {
			String response = null;
			
			try {
				response = webInvoke(methodName, params);
			} catch (Exception e) {
				response = "error";
			}

			return response;
		} else {
			Log.e(WSC_TAG, "Unkown HTTP method!");
			return "error";
		}
	}

	@Override
	protected void onPostExecute(String result) {
		callback.response(result);
		if (ShowNewsActivity.dialog != null) {
			if (ShowNewsActivity.dialog.isShowing()) {
				ShowNewsActivity.dialog.dismiss();
			}
		}
	}

}